﻿// -----------------------------------------------------------------------
// <copyright file="Updater.cs" company="Support">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace SupportUpdater
{
    using System;
    using System.ComponentModel;
    using System.IO;
    using System.Net;
    using Ionic.Zip;
    using SupportUpdater.Properties;

    /// <summary>
    /// Update Last Version Completed
    /// </summary>
    /// /// <param name="updatestatus">The update status.</param>
    public delegate void UpdateCompleted(string updatestatus);

    /// <summary>
    /// Value of Last Version Changed
    /// </summary>
    internal delegate void ValueChanged();

    /// <summary>
    /// Download Last Version Completed
    /// </summary>
    internal delegate void DownloadCompleted();

    /// <summary>
    /// Support System Updater Class
    /// </summary>
    public class Updater
    {
        /// <summary>
        /// Support System Updater Instance
        /// </summary>
        private static Updater instance = new Updater();

        /// <summary>
        /// A Web this.client Used to Get All Data Required for Update Process
        /// </summary>
        private WebClient client = new WebClient();

        /// <summary>
        /// Last Version FileName
        /// </summary>
        private string lastversion = Settings.Default.CurrentVersion;

        /// <summary>
        ///  Last Version URL on Server
        /// </summary>
        private string lastversionurl = Settings.Default.UpdateURL;

        /// <summary>
        /// Occurs when [last version updated].
        /// </summary>
        public event UpdateCompleted LastVersionUpdated;

        /// <summary>
        /// Occurs when [last version changed].
        /// </summary>
        internal event ValueChanged LastVersionChanged;

        /// <summary>
        /// Occurs when [last version downloaded].
        /// </summary>
        internal event DownloadCompleted LastVersionDownloaded;

        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value>The instance.</value>
        public static Updater Instance
        {
            get { return instance; }
        }

        /// <summary>
        /// Gets or sets the last version.
        /// </summary>
        /// <value>The last version.</value>
        private string LastVersion
        {
            get
            {
                return this.lastversion;
            }

            set
            {
                if ( value != this.lastversion )
                {
                    this.lastversion = value;
                    Settings.Default.CurrentVersion = value;
                    Settings.Default.Save();
                    this.lastversionurl += value;
                    this.LastVersionChanged();
                }
                else
                {
                    this.LastVersionUpdated("You Already Have The Latest Version");
                }
            }
        }

        /// <summary>
        /// Updates the version.
        /// </summary>
        /// <param name="directorypath">The directory path.</param>
        public void UpdateVersion( string directorypath )
        {
            Updater.Instance.LastVersionChanged += () => { Updater.Instance.DownloadLastVersionZipFile( directorypath ); };
            Updater.Instance.LastVersionDownloaded += () => { Updater.Instance.ExtractLastVersionZipFile( directorypath +"\\"+ this.lastversion ); };
            Updater.Instance.GetLastVersion();
        }

        /// <summary>
        /// Gets the last version.
        /// </summary>
        private void GetLastVersion()
        {
            this.client.DownloadStringAsync( new Uri( Settings.Default.LastVersionURL ) );
            this.client.DownloadStringCompleted += ( sender , e ) =>
                {
                    LastVersion = e.Result;
                };
        }

        /// <summary>
        /// Downloads the last version zip file.
        /// </summary>
        /// <param name="directorypath">The directory path.</param>
        private void DownloadLastVersionZipFile( string directorypath )
        {
            this.client.DownloadFileAsync( new Uri( this.lastversionurl ) , directorypath +"\\"+ this.lastversion );
            this.client.DownloadFileCompleted += ( sender , e ) =>
            {
                this.LastVersionDownloaded();
            };
        }

        /// <summary>
        /// Extracts the last version zip file.
        /// </summary>
        /// <param name="fullpath">The full path.</param>
        private void ExtractLastVersionZipFile( string fullpath )
        {
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += ( sender , e ) =>
            {
                using ( ZipFile File = ZipFile.Read( fullpath ) )
                {
                    foreach ( var item in File )
                    {
                        item.Extract( Path.GetDirectoryName( fullpath ) , ExtractExistingFileAction.OverwriteSilently );
                    }
                }
            };

            bw.RunWorkerCompleted += ( sender , e ) => { File.Delete( fullpath ); this.LastVersionUpdated("Updated Successfully"); };
            bw.RunWorkerAsync();
        }
    }
}